#ifndef _ASYNCTCPSOCKSSLIMPL_H_
#define _ASYNCTCPSOCKSSLIMPL_H_

#include "stdafx.h"

// openssl genrsa -des3 -out server.key 1024
// openssl req -new -key server.key -out server.csr
// openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

#define SSL_READ_HEAD 0
#define SSL_READ_BODY 1

class CTcpSocketSslImpl : public ITcpSocketSsl, public CUnknownImp
{
public:
    CTcpSocketSslImpl(void);
    virtual ~CTcpSocketSslImpl(void);

    BEGIN_STDCOM_MAP
    STDCOM_INTERFACE_ENTRY(ITcpSocketSsl)
    STDCOM_INTERFACE_ENTRY(ITcpSocket)
    STDCOM_INTERFACE_ENTRY_UNKNOWN_(ITcpSocketSsl)
    STDCOM_INTERFACE_MEMBER_ENTRY_(m_pReadOper, IOperation, IID_IReadOperation)
    STDCOM_INTERFACE_MEMBER_ENTRY_(m_pWriteOper, IOperation, IID_IWriteOperation)
    END_STDCOM_MAP

public:
    HRESULT CreateIoOperation(IAsynFrame* pIAsynFrame);
    HRESULT BindEvloop(ioevloop_t* loop);

public:
    // IIoDevice
    std_method(CloseIo)(UINT rw);
    std_method(BindIo)();
    std_method(OpenIo)();

    // ISocket
    std_method(BindEvent)(IBase* pSocketEvent);
    std_method(UnBindEvent)();
    std_method(CreateSock)();
    std_method(CloseSock)();
    std_method(IsOpen)();
    std_method(AttachSock)(_sock_t sock);
    std_method_(_sock_t, DetachSock)();
    std_method_(_sock_t, GetSock)();
    std_method(GetReadOperation)(IID id, IBase** pBase);
    std_method(GetWriteOperation)(IID id, IBase** pBase);

    // ITcpSocket
    std_method(ReadIo)(ULONG pos, ULONG size, crtid event, int tm);
    std_method(WriteIo)(ULONG pos, ULONG size, crtid event, int tm);
    std_method(ConnectIo)(NET_ADDR addr, NET_PORT port, crtid cid, int tm);

    // ITcpSocketSSL
    std_method(LoadCertificate)(UCHAR* buf, size_t size);
    std_method(SetSSLCtxAddress)(LPCSTR hostname);

public:
    std_method(OnEventcb)(short err, short what, _sock_t fd);
    std_method(OnReadcb)(short err, buf_ptr ptr, buf_len len);
    std_method(OnWritecb)(short err, buf_ptr ptr, buf_len len);

private:
    _sock_t m_sock;
    _lComPtr<IOperation> m_pReadOper;
    _lComPtr<IOperation> m_pWriteOper;
    _lComPtr<IOperation> m_pConnectOper;
    _lComPtr<ISockProc> m_pISockProc;
    SafePtr<ioevstream_t*, default_free_safeptr> m_stream;
    ioevloop_t* m_evloop;

    unsigned char m_buffer[1024];
    unsigned char m_sendbuffer[1024];
    unsigned char m_recvbuffer[1024];
    unsigned int m_rstate;
};

#endif
